package com.zy.multiredis.config;

import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;

import com.zy.multiredis.util.ManualRegistBeanUtil;

@Configuration
@ConditionalOnClass(MultiRedisTemplateMap.class)
public class MultiRedisAutoConfig {

    private ApplicationContext applicationContext;
    private ConfigurableListableBeanFactory beanFactory;

    public MultiRedisAutoConfig(ApplicationContext applicationContext, ConfigurableListableBeanFactory beanFactory) {
        this.applicationContext = applicationContext;
        this.beanFactory = beanFactory;
    }
    
    @Bean
    public MuitiRedisTemplateInjectAnnotationBeanPostProcessor configBeanPostProcessor() {
        MuitiRedisTemplateInjectAnnotationBeanPostProcessor beanPostProcessor = new MuitiRedisTemplateInjectAnnotationBeanPostProcessor(); 
        return beanPostProcessor;
    }

    @Bean("redisTemplate")
    @Primary
    @ConditionalOnMissingBean(RedisTemplate.class)
    public RedisTemplate configDefaultRedisTemplate(RedisConnectionFactory connectionFactory) {
        RedisTemplate template = new RedisTemplate<>();
        template.setConnectionFactory(connectionFactory);
        return template;
    }
    
//  @Bean("redis2")
//  public RedisTemplate configRedisTemplate2(multiRedisConnectionFactoryMap connectionFactoryMap) {
//      RedisTemplate template = new RedisTemplate<>();
//      template.setConnectionFactory(connectionFactoryMap.getRedisConnectionFactories().get("redis2"));
//      return template;
//  }
    
    @Bean
    @ConditionalOnMissingBean(MultiRedisTemplateMap.class)
    public MultiRedisTemplateMap configTemplate(MultiRedisConnectionFactoryMap redisConnectionFactories,Map<String,RedisTemplate> defaultRedisTemplates) {
        Map<String, RedisTemplate> redisTemplates = new LinkedHashMap<String, RedisTemplate>(defaultRedisTemplates);
        for (Map.Entry<String, RedisConnectionFactory> entry : redisConnectionFactories.getRedisConnectionFactories()
            .entrySet()) {
            // 创建tamplate,根据key作为spring中的类名
            // 首先判断容器中是否有
            if (beanFactory.containsBean(entry.getKey())) {
                Object bean = beanFactory.getBean(entry.getKey());
                if(bean instanceof RedisTemplate) {
                    redisTemplates.put(entry.getKey(),(RedisTemplate)bean);
                }
            }else{
                RedisTemplate redisTemplate =
                    ManualRegistBeanUtil.registerBeanWithProperties((ConfigurableApplicationContext)applicationContext,
                        entry.getKey(), RedisTemplate.class, new HashMap<String, Object>() {
                            {
                                put("connectionFactory", entry.getValue());
                            }
                        });
                redisTemplates.put(entry.getKey(), redisTemplate);
            }
        }
        return new MultiRedisTemplateMap(redisTemplates);
    }
}
